package top.byfree.jbyan.saber.bean.dto

import cn.dev33.satoken.secure.SaSecureUtil
import cn.dev33.satoken.stp.StpUtil
import jakarta.validation.constraints.Email
import jakarta.validation.constraints.NotBlank
import jakarta.validation.constraints.Pattern
import jakarta.validation.constraints.Size
import org.hibernate.validator.constraints.URL
import top.byfree.jbyan.saber.bean.IS_DELETE_NO
import top.byfree.jbyan.saber.bean.SECRET_KEY
import top.byfree.jbyan.saber.bean.USER_STATUS_NORMAL
import top.byfree.jbyan.saber.bean.pojo.User
import top.byfree.jbyan.saber.bean.vo.UserVo
import top.byfree.jbyan.saber.common.AddGroup
import top.byfree.jbyan.saber.common.UpdateGroup
import java.time.LocalDateTime

/**
 * 用户 Dto
 *
 * @author jbyan
 * @since 21/3/2024
 */
data class UserDto(
    /* 头像 */
    @field:URL(message = "用户头像必须符合URL格式")
    var avatar: String?,
    /* 用户名称 */
    @field:NotBlank(message = "用户名称不能为空", groups = [AddGroup::class])
    @field:Size(min = 4, max = 12, message = "用户名称需要在4-12位之间", groups = [AddGroup::class])
    @field:Pattern(regexp = "^[a-zA-Z0-9]+\$", message = "用户名称只能包含字母或数字", groups = [AddGroup::class])
    var username: String?,
    /* 用户昵称 */
    @field:Size(min = 2, max = 8, message = "用户昵称需要在2-8位之间")
    @field:NotBlank(message = "用户昵称不能为空")
    var nickname: String?,
    /* 用户密码 */
    @field:Size(min = 6, max = 12, message = "用户密码需要在6-12位之间", groups = [AddGroup::class])
    @field:Pattern(
        regexp = "^(?=.*[0-9])(?=.*[a-zA-Z])(?=.*[^a-zA-Z0-9]).{6,}\$",
        message = "用户密码需要包含字母、数字和特殊字符",
        groups = [AddGroup::class]
    )
    var password: String?,
    /* 用户签名 */
    @field:Size(max = 40, message = "用户签名需要在40个字符之内")
    var sign: String?,
    /* 邮箱 */
    @field:Email(message = "邮箱格式错误")
    var email: String?,
    /* 用户状态 */
    var status: Int = 0
) {

    fun toUser(cUserId: String? = null, type: Class<*> = UpdateGroup::class.java): User {
        val userVo = (StpUtil.getSession().get("user") as? UserVo)!!
        val user = User {
            userId = cUserId?.let { cUserId } ?: userVo.userId
            gmtModify = LocalDateTime.now()
            modifyBy = userVo.username
            status = this@UserDto.status
        }
        nickname?.let { user.nickname = it }
        username?.let { user.username = it }
        password?.let { user.password = SaSecureUtil.aesEncrypt(SECRET_KEY, it) }
        email?.let { user.email = it }
        sign?.let { user.sign = it }
        avatar?.let { user.avatar = it }

        if (type == AddGroup::class.java) {
            user.createBy = userVo.username
            user.gmtCreate = LocalDateTime.now()
            user.isDelete = IS_DELETE_NO
        }

        return user
    }
}